
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:gun/entity/inventory_result_entity.dart';
import 'package:gun/http/api.dart';
import '../entity/book_entity.dart';
import '../event/inventory_event.dart';
import '../main.dart';
import '../util/analysis_book_rule.dart';
import '../widget/dialog.dart';

class Inventory extends StatefulWidget {
  const Inventory({Key? key}) : super(key: key);

  @override
  State<Inventory> createState() => _InventoryState();
}

class _InventoryState extends State<Inventory> {

  RxnString floor = RxnString();
  String? placeNo;
  RxInt total = RxInt(0);
  RxInt has = RxInt(0);
  RxInt borrowed = RxInt(0);
  RxInt lose = RxInt(0);
  RxInt wrong = RxInt(0);
  RxInt unKnow = RxInt(0);
  RxList<BookEntity> bookList = RxList();
  RxList<BookEntity> filterList = RxList();
  RxInt tab = RxInt(100);
  bool isRequesting = false;

  StreamSubscription? subscription;

  @override
  initState() {
    super.initState();
    subscription = eventFactory.on<InventoryEvent>().listen((event) {
      _analyze(event.data);
    });
    player.play('audio/scan_place.mp3');
  }

  @override
  void dispose() {
    subscription?.cancel();
    subscription = null;
    super.dispose();
  }

  _analyze(String epc){
    if(placeNo == null){
      if(epc.startsWith('B0')){
        try{
          var length = int.parse(epc.substring(2,4));
          placeNo = epc.substring(4,4+length);
          _findPlace(placeNo);
          return;
        }catch(e){
          print(e);
        }
      }
    }else{
      if(!epc.startsWith('B0') && hasFinish){

        try{
          var no = analysisBookNoRule(epc);
          if(no == null || no.isEmpty){
            return;
          }
          var item = bookList.firstWhereOrNull((element) => element.no == no);
          if(item == null){
            bookList.add(BookEntity()..no = no);
            _findBook(no);
          }else{
            var index = bookList.indexOf(item);
            bookList.removeAt(index);
            item.hasRfid = true;
            item.result = _getResultStatus(item);
            bookList.insert(index, item);
            _calculate();
          }
        }catch(e){
          print(e);
        }
      }
    }
  }


  _findPlace(no) async {
    var name = await findPlace(no);
    if(name != null){
      floor.value = name;
      player.play('audio/scan_book.mp3');
      _findRfidBooks(no);
    }else{
      placeNo = null;
    }
  }

  bool hasFinish = false;

  _findRfidBooks(no) async {
    var books = await findRfidPlaceBook(no);
    if(books!=null) {
      bookList.addAll(books);
      hasFinish = true;
      _calculate();
      _startGetStatus();

    }
  }

  //查询馆藏状态
  _startGetStatus(){
    var next = bookList.firstWhereOrNull((element) => element.status == -1);
    if(next != null){
      _getStatus(next);
    }
  }

  _getStatus(BookEntity book) async {
    if(isRequesting){
      return;
    }
    isRequesting = true;
    var result = await findBook(book.no);
    if(result.$1 == 429){
      isRequesting = false;
      Future.delayed(const Duration(seconds: 1),(){
        _startGetStatus();
      });
      return;
    }
    var index = bookList.indexOf(book);
    bookList.removeAt(index);
    if(result.$1 == 200 && result.$2 != null){
      if(result.$2.stateValue == 'in'){
        book.status = 0;
      }
      if(result.$2.stateValue == 'borrowed'){
        book.status = 1;
      }
    }else{
      book.status = -2;
    }
    book.result = _getResultStatus(book);
    bookList.insert(index, book);
    _calculate();
    isRequesting = false;
    _startGetStatus();
  }

  //最终状态
  _getResultStatus(BookEntity item){
    var result = 4;
    if(item.hasApi && item.hasRfid && placeNo == item.placeNo && (item.status == 0 || item.status == 1)){
      result = 0;
    }
    if(item.hasApi && !item.hasRfid && placeNo == item.placeNo && item.status == 1){
      result = 1;
    }
    if(item.hasApi && !item.hasRfid && placeNo == item.placeNo && item.status == 0){
      result = 2;
    }
    if(!item.hasApi && item.hasRfid && placeNo != item.placeNo && (item.status == 0 || item.status == 1)){
      result = 3;
    }
    return result;
  }

  _calculate(){
    total.value = bookList.length;
    has.value = bookList.where((e) => e.result == 0).length;
    borrowed.value = bookList.where((e) => e.result == 1).length;
    lose.value = bookList.where((e) => e.result == 2).length;
    wrong.value = bookList.where((e) => e.result == 3).length;
    unKnow.value = bookList.where((e) => e.result == 4).length;
  }



  _findBook(no) async {
    var book = await findRfidBook(no);
    if(book!=null && book.no != null) {
      book.hasRfid = true;
      bookList.removeWhere((element) => element.no == no);
      bookList.add(book);
      _calculate();
      _startGetStatus();
    }
  }

  _title(){
    return Container(
        margin: EdgeInsets.only(top: 30.h),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            InkWell(
              onTap: (){
                Get.back();
              },
              child: Row(
                children: [
                  const Icon(Icons.arrow_back_ios_new,color: Colors.white,),
                  Text("返回",style: TextStyle(color: Colors.white,fontSize: 16.sp),)
                ],
              )
            ),
            Image.asset("assets/images/inventory_title.png",width: 100.w,fit: BoxFit.fitWidth,),
            InkWell(
              onTap: (){
                DialogWidget().settingDialog();
              },
              child: Text("调整功率",style: TextStyle(color: Colors.white,fontSize: 16.sp),),
            )
          ],
        )
    );
  }

  _info(){
    return Container(
      width: double.infinity,
      height: 65.h,
      margin: EdgeInsets.only(top: 10.r),
      padding: EdgeInsets.only(left: 26.r,right: 16.r),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(6.r)),
      ),
      child: Obx(() => Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text("应有\n${total.value}",style: TextStyle(color: Colors.blue,fontSize: 16.sp),textAlign: TextAlign.center,),
          const VerticalDivider(color: Colors.grey,width: 1,),
          Text("在架\n${has.value}",style: TextStyle(color: Colors.blue,fontSize: 16.sp),textAlign: TextAlign.center),
          Text("外借\n${borrowed.value}",style: TextStyle(color: const Color.fromARGB(255, 20, 196, 196),fontSize: 16.sp),textAlign: TextAlign.center),
          Text("缺失\n${lose.value}",style: TextStyle(color: Colors.red,fontSize: 16.sp),textAlign: TextAlign.center),
          Text("错架\n${wrong.value}",style: TextStyle(color: const Color.fromARGB(255, 251, 82, 28),fontSize: 16.sp),textAlign: TextAlign.center),
          Text("未知\n${unKnow.value}",style: TextStyle(color:  Colors.grey,fontSize: 16.sp),textAlign: TextAlign.center),
        ],
      )),
    );
  }

  _tab(){
    return Container(
      width: double.infinity,
      height: 80.h,
      margin: EdgeInsets.only(top: 10.r),
      padding: EdgeInsets.all(16.r),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(6.r)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              // Image.asset("assets/images/icon_floor.png",width: 20.w,fit: BoxFit.fitWidth,),
              Text(" 层架信息：",style: TextStyle(color: Colors.black,fontSize: 16.sp),),
              Obx(() => Text(floor.value??'',maxLines:2,style: TextStyle(color: const Color.fromARGB(255, 20, 196, 196),fontSize: 16.sp),)),
            ],
          ),
          // Obx(() => Text(floor.value??'',maxLines:2,style: TextStyle(color: Colors.black,fontSize: 16.sp),)),
          SizedBox(height: 8.h,),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              _tabWidget("全部",100),
              _tabWidget("在架",0),
              _tabWidget("外借",1),
              _tabWidget("缺失",2),
              _tabWidget("错架",3),
              _tabWidget("未知",4),
            ],
          ),
        ],
      ),
    );
  }

  _tabWidget(msg,index){
    return Obx(() => InkWell(
      onTap: (){
        tab.value = index;
      },
      child: Text(msg,style: TextStyle(color: Colors.transparent,fontSize: 16.sp,
          shadows: [Shadow(color: tab.value==index?Colors.blue:Colors.grey, offset: const Offset(0, -3))],
          decoration: tab.value==index?TextDecoration.underline:TextDecoration.none,decorationColor:Colors.blue,decorationThickness: 2),),
    ));
  }

  _scanFloorExample(){
    return SizedBox(
      height: 350.h,
      child: Stack(
        alignment: AlignmentDirectional.center,
        children: [
          Image.asset("assets/images/scan_floor.png",width: 340.w,fit: BoxFit.fitWidth,),
          Positioned(
            top: 170.h,
            right: 0,
            child: Image.asset("assets/images/gun.gif",width: 180.w,fit: BoxFit.fitWidth,),
          ),
          Positioned(
              top: 300.h,
              child: Text("请扫描层架标签",style: TextStyle(color: Colors.white,fontSize: 22.sp,fontWeight: FontWeight.bold),)
          )

        ],
      )
    );
  }

  _scanBookExample(){
    return SizedBox(
        height: 350.h,
        child: Stack(
          alignment: AlignmentDirectional.center,
          children: [
            Image.asset("assets/images/scan_book.png",width: 340.w,fit: BoxFit.fitWidth,),
            Positioned(
              top: 170.h,
              right: 0,
              child: Image.asset("assets/images/gun.gif",width: 180.w,fit: BoxFit.fitWidth,),
            ),
            Positioned(
                top: 300.h,
                child: Text("请扫描层架上的图书",style: TextStyle(color: Colors.white,fontSize: 22.sp,fontWeight: FontWeight.bold),)
            )
          ],
        )
    );
  }

  _list(){
    return Obx(() => Container(
      height: 310.h,
      margin: EdgeInsets.only(bottom: 10.r),
      child: ListView.builder(
        itemBuilder: (context, index) {
          return _listItem(index);
        },
        itemCount: tab.value == 100?bookList.length:bookList.where((e) => e.result == tab.value).length,
      )
    ));
  }

  _listItem(index){
    var item = tab.value == 100?bookList[index]:bookList.where((e) => e.result == tab.value).toList()[index];
    return Container(
      margin: EdgeInsets.only(top: 10.r),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(6.r)),
      ),
      padding: EdgeInsets.all(10.r),
      child: Column(
        children: [
          InkWell(
            onTap: (){
              var index = bookList.indexOf(item);
              bookList.removeAt(index);
              item.expand = !item.expand;
              bookList.insert(index, item);
            },
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                SizedBox(width: 230.w,child:Text('${item.mainTitle}'),),
                Container(
                    width: 70.w,
                    height: 30.h,
                    margin: EdgeInsets.only(left: 10.r),
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                      color: item.result == 0?Colors.blue :
                      item.result == 1?const Color.fromARGB(255, 20, 196, 196) :
                      item.result == 2?Colors.red:
                      item.result == 3?const Color.fromARGB(255, 251, 82, 28):
                      Colors.grey,
                      borderRadius: BorderRadius.all(Radius.circular(6.r)),
                    ),
                    child: Text(item.result == 0?"在架" :item.result == 1?"外借" :item.result == 2?"缺失":item.result == 3?"错架":"未知"
                      ,style: const TextStyle(color: Colors.white),)
                ),
                Icon(item.expand?Icons.keyboard_arrow_up_rounded:Icons.keyboard_arrow_down_rounded,color: Colors.grey,)
              ],
            ),
          ),
          if(item.expand)...
            [
              Column(
                children: [
                  SizedBox(height: 6.h,),
                  Divider(height: 0.5.h, indent: 4.w, endIndent: 4.w, color: const Color.fromRGBO(86, 169, 255, 1),),
                  SizedBox(height: 6.h,),
                  Row(
                    children: [
                      const Text('存放位置：'),
                      Text('${item.placeName}',style: const TextStyle(color: Color.fromARGB(255, 20, 196, 196)),),
                    ],
                  ),
                  Row(
                    children: [
                      const Text('馆藏状态：'),
                      Text(item.status == -1?'待查询':item.status == -2?'未知':item.status == 0?"在馆":"外借",
                        style: TextStyle(color: item.status == -1?Colors.red:item.status == -2?const Color.fromARGB(255, 251, 82, 28):item.status == 0?Colors.blue:const Color.fromARGB(255, 20, 196, 196)),),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text('条码号：${item.no}'),
                      Text('索书号：${item.searchNo}'),
                    ],
                  )
                ],
              )
            ]
        ],
      )
    );
  }


  _getTypeBooks(type){
    var list = [];
    bookList.where((e) => e.result == type).forEach((element) {
      list.add(InventoryResultEntity()
        ..no = element.no
        ..stateValue = element.stateValue
        ..placeNo = element.placeNo
      );
    });
    return list;
  }


  _action(){
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
          InkWell(
            onTap: () async {
              var result = await inventory(placeNo, _getTypeBooks(0), _getTypeBooks(1), _getTypeBooks(2), _getTypeBooks(3), _getTypeBooks(4));
              if(result){
                Get.back();
              }
            },
            child: Image.asset("assets/images/inventory_done.png",width: 140.w,fit: BoxFit.fitWidth,),
          ),
          InkWell(
            onTap: ()  async {
              var result = await inventory(placeNo, _getTypeBooks(0), _getTypeBooks(1), _getTypeBooks(2), _getTypeBooks(3), _getTypeBooks(4));
              if(result){
                floor.value = null;
                placeNo = null;
                total.value = 0;
                has.value = 0;
                borrowed.value = 0;
                lose.value = 0;
                wrong.value = 0;
                unKnow.value = 0;
                bookList.clear();
                tab.value = 100;
                isRequesting = false;
                hasFinish = false;
              }
              player.play('audio/scan_place.mp3');

            },
            child: Image.asset("assets/images/inventory_next.png",width: 140.w,fit: BoxFit.fitWidth,),
          )
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Container(
        width: double.infinity,
        height: double.infinity,
        padding: EdgeInsets.only(left: 20.r,right: 20.r),
        decoration: const BoxDecoration(
          image: DecorationImage(
            fit: BoxFit.fill,
            image: AssetImage(
              "assets/images/bg.png",
            ),
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            _title(),
            SizedBox(height: 20.h,),
            _info(),
            SizedBox(height: 16.h,),
            _tab(),
            Obx(() => floor.value == null?_scanFloorExample():total.value == 0?_scanBookExample():_list()),
            Obx(() => Visibility(visible:total.value > 0,child: _action(),))
          ],
        )
      ),
    );
  }
}